#pragma once
#include <exception>
#include <stdexcept>
#include <sstream>
#include <string>

#define THROW(type, msg) \
    do { \
        std::ostringstream os; \
        os << __FILE__ << ':' << __LINE__ << ' ' << __FUNCTION__ \
           << " \"" << (msg) << "\""; \
        throw type(os.str().c_str()); \
    } while (0)

#define REQUIRE(cond, msg) \
    do { \
        if (!(cond)) { \
            THROW(std::runtime_error, (msg)); \
        } \
    } while (0)

#ifndef NDEBUG 
#define ASSERT(cond) \
    do { \
        if (!(cond)) { \
            THROW(std::logic_error, std::string("Assertion failed: ") + #cond); \
        } \
    } while (0)
#else
#define ASSERT(cond)
#endif
    
 

